# -*- coding: utf-8 -*-

#   This file is part of emesene.
#
#    Emesene is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    emesene is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with emesene; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA


import gtk
import os
import gobject
import Theme
import htmltextview
import desktop
from emesenelib import soap
import dialog
import abstract.stock

HAVE_WEBCAM = 1
try:
    import WebcamDevice
except:
    print 'Webcam unavailable'
    HAVE_WEBCAM = 0
# gstreamer and /dev/ folder is not in windows or mac, isn't it?
if os.name != 'posix':
    HAVE_WEBCAM = 0
    
from Widgets import WidgetToggleBox

class PreferenceWindow(gtk.Window):
    '''This class display a windows where the user
    can modify the behaviour of emesene'''

    def __init__(self, controller, config, parent):
        '''Contructor'''
        gtk.Window.__init__(self)

        self.controller = controller
        self.set_default_size(150, 150)
        self.set_title(_('Preferences'))
        self.set_role('preferences')
        self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
        self.set_position(gtk.WIN_POS_CENTER_ALWAYS)
        self.set_resizable(False)
        pix = self.render_icon(gtk.STOCK_PREFERENCES, gtk.ICON_SIZE_MENU)
        self.set_icon(pix)


        self.config = config
        self.set_transient_for(parent)

        self.set_border_width(6)
        vbox = gtk.VBox()
        vbox.set_spacing(4)
        hButBox = gtk.HButtonBox()
        hButBox.set_spacing(4)
        hButBox.set_layout(gtk.BUTTONBOX_END)
        notebook = gtk.Notebook()
        notebook.set_scrollable(True)
        notebook.set_border_width(3)
        bClose = gtk.Button(stock=gtk.STOCK_CLOSE)

        vbox.pack_start(notebook, True, True)
        hButBox.pack_start(bClose)
        vbox.pack_start(hButBox, False, False)

        if self.controller.connected:
            self.interface_tab = InterfaceTab(self.controller)
            self.themesTab = ThemesTab(self.controller)
            self.colorSchemeTab = ColorSchemeTab(self.controller)
            self.ftTab = FTSettings(self.controller)
            self.privacyTab = PrivacyTab(self.controller)
            if HAVE_WEBCAM:
                self.webcamTab = WebcamTab(self.controller)
            notebook.append_page(self.themesTab, gtk.Label(_('Theme')))
            notebook.append_page(self.interface_tab, gtk.Label(_('Interface')))
            notebook.append_page(self.colorSchemeTab,
                gtk.Label(_('Color scheme')))
            notebook.append_page(self.ftTab,
                gtk.Label(_('Filetransfer')))
            notebook.append_page(self.privacyTab, gtk.Label(_('Privacy')))

        self.desktopTab = DesktopTab(self.controller)
        self.connectionTab = ConnectionTab(self.config)

        if self.controller.connected:
            notebook.append_page(self.desktopTab, gtk.Label(_('Desktop')))
            notebook.append_page(self.connectionTab, gtk.Label(_('Connection')))
            if HAVE_WEBCAM:
                notebook.append_page(self.webcamTab, gtk.Label(_('Webcam')))
        else:
            notebook.append_page(self.connectionTab, gtk.Label(_('Connection')))
            notebook.append_page(self.desktopTab, gtk.Label(_('Desktop')))


        vbox.show_all()
        self.add(vbox)

        self.connect('delete-event', self.close)
        bClose.connect('clicked', self.close)

    def close(self, *args):
        '''Close the window'''
        self.hide()
        self.save()
        self.destroy()
        self.controller.preference_open = False

    def save(self):
        '''save the actual setting'''

        self.connectionTab.save()
        self.desktopTab.save()

        if self.controller.connected:
            self.interface_tab.save()
            self.themesTab.save()
            self.colorSchemeTab.save()
            self.desktopTab.save()
            self.ftTab.save()
            if HAVE_WEBCAM:
                self.webcamTab.save()
            # TODO: remove preferences-changed
            self.controller.emit('preferences-changed')

class ColorSchemeItem:
    def __init__(self, tab, configColor,text):
        self.configColor=configColor
        self.button = gtk.ColorButton(gtk.gdk.color_parse(tab.config.user[configColor]))
        self.button.connect('color-set', tab.save)
        alignment = gtk.Alignment(0, 0.5, 0, 0)
        alignment.add(gtk.Label(text))
        self.hbox = gtk.HBox()
        self.hbox.pack_start(alignment, True, True, 3)
        self.hbox.pack_start(self.button, False, False, 3)

class ColorSchemeTab(gtk.VBox):
    '''This class represent the tab that contain all the configuration about the colors'''

    def __init__(self, controller):
        gtk.VBox.__init__(self)

        self.config = controller.config
        self.controller = controller

        self.items={}
        self.items['typingColor'] = ColorSchemeItem(self, 'typingColor', \
            _('Contact typing'))
        self.items['messageWaitingColor'] = ColorSchemeItem(self, \
            'messageWaitingColor', _('Message waiting'))
        self.items['personalMessageColor'] = ColorSchemeItem(self, \
            'personalMessageColor', _('Personal msn message'))

        vbox = gtk.VBox()

        for i in self.items.keys():
            vbox.pack_start(self.items[i].hbox, False, False, 3)

        #scroll = gtk.ScrolledWindow()
        #scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
        #scroll.add_with_viewport(vbox)

        #self.pack_start(scroll, True, True, 0)
        self.pack_start(vbox, True, True, 0)
        self.pack_start(gtk.HSeparator(), False, True, 2)

        restoreButton = gtk.Button(stock = gtk.STOCK_CLEAR)
        restoreButton.connect('clicked', self.restoreColors)

        alignment = gtk.Alignment(0.5, 0.5, 0.5, 0.5)
        alignment.add(restoreButton)
        self.pack_start(alignment, False, True, 2)

        self.show_all()

    def restoreColors(self, *args):
        for i in self.items.keys():
            color = gtk.gdk.color_parse(self.config.user.getDefault(self.items[i].configColor))
            self.items[i].button.set_color(color)

    def save(self, *args):
        for i in self.items.keys():
            self.config.user[self.items[i].configColor] = rgbToHexa(self.items[i].button.get_color())


class DesktopTab(gtk.VBox):
    '''A tab that lets the user override the detected desktop settings'''

    def __init__(self, controller):
        gtk.VBox.__init__(self)

        self.config = controller.config

        self.urlSettings = UrlSettings(controller.config)
        frame1 = gtk.Frame(_('Links and files'))
        frame1.set_border_width(4)
        frame1.add(self.urlSettings)
        
        self.emailSettings = EmailSettings(controller.config)
        frame2 = gtk.Frame(_('E-mails'))
        frame2.set_border_width(4)
        frame2.add(self.emailSettings)

        self.set_spacing(8)
        self.set_border_width(8)

        self.rgba = gtk.CheckButton(_('Enable rgba colormap (requires restart)'))
        self.rgba.set_active(self.config.glob['rgbaColormap'])

        self.disableTray = gtk.CheckButton(_('Disable tray icon (requires restart)'))
        self.disableTray.set_active(self.config.glob['disableTrayIcon'])

        self.pack_start(self.rgba, False)
        self.pack_start(self.disableTray, False)
        self.pack_start(frame1, False)
        self.pack_start(frame2, False)

    def save(self, widget=None):
        self.config.glob['rgbaColormap'] = self.rgba.get_active()
        self.config.glob['disableTrayIcon'] = self.disableTray.get_active()
        self.urlSettings.save()
        self.emailSettings.save()
        
class EmailSettings(gtk.VBox):
    def __init__(self, config):
        gtk.VBox.__init__(self)

        self.set_spacing(8)
        self.set_border_width(8)

        self.config = config

        markup = _('By default, your e-mails will be opened with <b>your webbrowser</b>.'
                'But you can change these settings, deciding to open you e-mails with a specific e-mail program.')

        self.infolabel = gtk.Label()
        self.infolabel.set_markup(markup)
        self.infolabel.set_line_wrap(True)
        self.infolabel.set_alignment(0.0, 0.0)

        self.hboxentry = gtk.HBox()
        self.entry = gtk.Entry()
        self.entry.connect('activate', self.save)
        self.hboxentry.pack_start(gtk.Label(_('Command line:')), False)
        self.hboxentry.pack_start(self.entry)

        self.override = gtk.CheckButton(_('Override default settings'))
        self.override.set_active(self.config.glob['overrideMail'] != '')
        self.override.connect('toggled', self.toggleOverride)

        self.hboxtest = gtk.HBox()
        self.testbutton = gtk.Button(_('Click to test'))
        self.testbutton.connect('clicked', self.testMail)
        self.hboxtest.pack_start(gtk.Label())
        self.hboxtest.pack_start(self.testbutton, False, True, 6)

        self.pack_start(self.infolabel, False)
        self.pack_start(self.override, False)
        self.pack_start(self.hboxentry, False)
        self.pack_start(self.hboxtest, False)

        self.toggleOverride()

    def toggleOverride(self, override=None):
        active = self.override.get_active()
        self.hboxentry.set_sensitive(active)
        self.hboxtest.set_sensitive(active)
        if active:
            self.entry.set_text(self.config.glob['overrideMail'])
        else:
            self.entry.set_text('')
        self.save()

    def save(self, widget=None):
        self.config.glob['overrideMail'] = self.entry.get_text()

    def testMail(self, button):
        self.save()
        try:
            os.popen(self.config.glob['overrideMail'])
        except OSError:
            pass

class UrlSettings(gtk.VBox):
    def __init__(self, config):
        gtk.VBox.__init__(self)

        self.set_spacing(8)
        self.set_border_width(8)

        self.config = config

        detected = desktop.get_desktop(True)
        if detected:
            commandline = ' '.join(desktop.get_command(detected, '')).strip()
            tmp = {
                'detected': detected,
                'commandline': commandline,
            }
            markup = _('The detected desktop environment is '
                '<b>"%(detected)s"</b>.\n'
                '<span face="Monospace">%(commandline)s</span> '
                'will be used to open links and files') % tmp
        else:
            markup = _('<b>No desktop environment detected.</b> '
                'The first browser found will be used to open links')

        self.infolabel = gtk.Label()
        self.infolabel.set_markup(markup)
        self.infolabel.set_line_wrap(True)
        self.infolabel.set_alignment(0.0, 0.0)

        self.hboxentry = gtk.HBox()
        self.entry = gtk.Entry()
        self.entry.connect('activate', self.save)
        self.hboxentry.pack_start(gtk.Label(_('Command line:')), False)
        self.hboxentry.pack_start(self.entry)

        self.override = gtk.CheckButton(_('Override detected settings'))
        self.override.set_active(self.config.glob['overrideDesktop'] != '')
        self.override.connect('toggled', self.toggleOverride)

        self.helplabel = gtk.Label()
        self.helplabel.set_markup(_('<i>Note:</i> %s is replaced by '
            'the actual url to be opened') % '%url%')
        self.helplabel.set_alignment(0.5, 1.0)

        self.hboxtest = gtk.HBox()
        self.testbutton = gtk.Button(_('Click to test'))
        self.testbutton.connect('clicked', self.testDesktop)
        self.hboxtest.pack_start(gtk.Label())
        self.hboxtest.pack_start(self.testbutton, False, True, 6)

        self.pack_start(self.infolabel, False)
        self.pack_start(self.override, False)
        self.pack_start(self.hboxentry, False)
        self.pack_start(self.hboxtest, False)
        self.pack_start(self.helplabel, False)

        self.toggleOverride()

    def toggleOverride(self, override=None):
        active = self.override.get_active()
        self.hboxentry.set_sensitive(active)
        self.hboxtest.set_sensitive(active)
        if active:
            self.entry.set_text(self.config.glob['overrideDesktop'])
        else:
            self.entry.set_text('')
        self.save()


    def save(self, widget=None):
        desktop.override = self.entry.get_text()
        self.config.glob['overrideDesktop'] = self.entry.get_text()

    def testDesktop(self, button):
        self.save()
        try:
            desktop.open('http://www.emesene.org')
        except OSError:
            pass

class ConnectionTab(gtk.VBox):
    '''This class represent the tab that contains the connection options'''

    def __init__(self, config):
        '''Constructor'''

        gtk.VBox.__init__(self)

        self.config = config

        self.set_spacing(8)
        self.set_border_width(8)

        self.debug = gtk.CheckButton(_('_Show debug in console'))
        self.debug.set_active(self.config.glob['debug'])
        self.binary = gtk.CheckButton(_('_Show binary codes in debug'))
        self.binary.set_active(self.config.glob['binary'])
        self.httpMethod =  gtk.CheckButton(_('_Use HTTP method'))
        self.httpMethod.set_active(self.config.glob['httpMethod'])
          
        self.proxySettings = ProxySettings(self.config)
        frame = gtk.Frame(_('Proxy settings'))
        frame.set_border_width(4)
        frame.add(self.proxySettings)

        self.pack_start(self.debug, False, False)
        self.pack_start(self.binary, False, False)
        self.pack_start(self.httpMethod, False, False)
        
        if self.config.currentUser != '':
            self.sendKeepalive = gtk.CheckButton(_('_Keepalive opened conversations'))
            self.sendKeepalive.set_active(self.config.user['sendKeepalive'])
            self.pack_start(self.sendKeepalive, False, False)
            self.receiveP4context = gtk.CheckButton(_('Support msn _groups friendly names (restart required)'))
            self.receiveP4context.set_active(self.config.user['receiveP4context'])
            self.pack_start(self.receiveP4context, False, False)
                
        proxyBox = gtk.VBox(spacing=2)
        proxyBox.set_border_width(4)
        proxyBox.pack_start(frame, False, False)

        self.pack_start(proxyBox, True, True)

        self.show_all()

    def save(self):
        '''save the actual setting'''

        self.config.glob['debug'] = self.debug.get_active()
        self.config.glob['binary'] = self.binary.get_active()
        self.config.glob['httpMethod'] = self.httpMethod.get_active()
        if self.config.currentUser != '':
            self.config.user['sendKeepalive'] = self.sendKeepalive.get_active()
            self.config.user['receiveP4context'] = self.receiveP4context.get_active()
        self.proxySettings.save()



class ThemesTab(gtk.VBox):
    '''This class represent the tab that ...'''

    def __init__(self, controller):
        '''Constructor'''

        gtk.VBox.__init__(self)

        self.controller = controller
        self.config = controller.config
        self.theme = controller.theme
        self.basetheme = Theme.BaseTheme()
        self.basetheme.pixbufs = {}
        self.basetheme.defaults = {}
        self.basetheme.HOME_PATH = self.theme.HOME_PATH
        self.basetheme.SYSTEM_WIDE_PATH = self.theme.SYSTEM_WIDE_PATH
        self.basetheme.defaultPath = self.theme.defaultPath

        self.set_spacing(8)
        self.set_border_width(8)

        self.smallIcons = gtk.CheckButton(_('_Use small icons'))
        self.smallIcons.set_active(self.config.user['smallIcons'])
        self.parseSmilies = gtk.CheckButton(_('Display _smiles'))
        self.parseSmilies.set_active(self.config.user['parseSmilies'])
        self.disableFormat = gtk.CheckButton(_('Disable text formatting'))
        self.disableFormat.set_active(self.config.user['disableFormat'])
        self.canResize = gtk.CheckButton(_('_Auto-resize big emoticons:\nmay be resource hungry but only when emoticon is visible'))
        self.canResize.set_active(self.config.user['canResizeEmoticons'])
        
        self.pack_start(self.smallIcons, False, False)
        self.pack_start(self.parseSmilies, False, False)
        self.pack_start(self.disableFormat, False, False)
        self.pack_start(self.canResize, False, False)

        fields = []

        fields.append({'name': 'theme',
                       'label': _('Theme'),
                       'values': self.config.getThemes(),
                       'config': None,
                       'sample': self.getThemeSample,
                       })

        fields.append({'name': 'smilieTheme',
                       'label': _('Smilie theme'),
                       'values': self.config.getSmilieThemes(),
                       'config': None,
                       'sample': self.getSmilieSample,
                       })

        fields.append({'name': 'conversationLayout',
                       'label': _('Conversation Layout'),
                       'values': self.controller.conversationLayoutManager.listAvailableThemes(),
                       'config': self.configConversationLayout,
                       'sample': None,
                       })

        self.fields = fields

        table = gtk.Table(len(fields), 2, False)
        table.set_row_spacings(2)
        table.set_col_spacings(2)
        row = 0
        for field in fields:
            label = gtk.Label(field['label'])
            label.set_alignment(0.0, 0.5)
            label.set_use_underline(True)
            table.attach(label, 0,1, row,row+1)

            comboModel = gtk.ListStore(str, gtk.gdk.Pixbuf)
            combo = gtk.ComboBox(comboModel)
            cellRenderer = gtk.CellRendererText()
            sampleImage = gtk.CellRendererPixbuf()
            sampleImage.set_property('xalign', 1.0)

            combo.pack_start(cellRenderer, False)
            combo.add_attribute(cellRenderer, 'markup', 0)
            combo.pack_start(sampleImage, True)
            combo.add_attribute(sampleImage, 'pixbuf', 1)

            self.fields[row]['combo'] = combo
            label.set_mnemonic_widget(combo)
            combo.connect('changed', self.save, field['name'])

            default = self.config.user[field['name']]
            done = False
            count = 0
            for current in field['values']:
                sample = None
                if field['sample']:
                    sample = field['sample'](field['name'], current)
                if not done:
                    if current == default: done = True
                    else: count += 1
                comboModel.append([ current, sample ])
            combo.set_active(count)
            table.attach(combo, 1,2, row,row+1)

            #button = gtk.Button(_('Edit...'))

            #if field['config']:
            #    table.attach(button, 2,3, row,row+1)
            #    button.connect('clicked', field['config'])
            #else:
            #    button.set_sensitive(False)

            row += 1
        self.pack_start(table, False, False, 3)
        self.show_all()

    # Config dialogs
    def configConversationLayout(self, *args):
        dialog = gtk.Dialog(_('Conversation Layout'),
                             None,
                             gtk.DIALOG_MODAL,
                             (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
        conversationLayoutTab = ConversationLayoutTab(self.controller)
        dialog.vbox.add(conversationLayoutTab)
        dialog.show_all()
        response = dialog.run()
        dialog.destroy()
        # do something with the changes here

    # Samples
    def getThemeSample(self, label, item):
        self.basetheme.setTheme(item)
        return self.basetheme.getImage('icon')

    def getSmilieSample(self, label, item):
        tempTheme = Theme.SmilieTheme(None, item)
        try:
            icon = tempTheme.getSmiley(':D').get_static_image()
            del tempTheme
            return icon
        except:
            pass

    # Other functions
    def save(self, widget = None, name = 'all'):
        self.config.user['parseSmilies'] = self.parseSmilies.get_active()
        self.config.user['smallIcons'] = self.smallIcons.get_active()
        self.config.user['disableFormat'] = self.disableFormat.get_active()
        self.config.user['canResizeEmoticons'] = self.canResize.get_active()
        
        try:
            for field in self.fields:
                self.config.user[field['name']] = field['combo'].get_active_text()
        except:
            pass

        if name in ('all','conversationLayout'):
            layout = self.config.user['conversationLayout']
            self.controller.conversationLayoutManager.load(layout)

#TODO: this is not a tab
class ConversationLayoutTab(gtk.VBox):
    '''This class represents the conversation layout config'''

    def __init__(self, controller):
        '''Constructor'''
        gtk.VBox.__init__(self)

        self.controller = controller
        self.config = controller.config

        self.set_spacing(8)
        self.set_border_width(8)

        # Preview field
        self.labelName = gtk.Label()
        self.labelName.set_alignment(0.0, 0.5)
        self.labelDescription = gtk.Label()
        self.labelDescription.set_alignment(0.0, 0.5)
        self.labelAuthor = gtk.Label()
        self.labelAuthor.set_alignment(0.0, 0.5)
        self.labelWebsite = gtk.Label()
        self.labelWebsite.set_alignment(0.0, 0.5)
        self.previewScroll = gtk.ScrolledWindow()
        self.previewScroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
        self.preview = htmltextview.HtmlTextView(self.controller)
        self.previewScroll.add(self.preview)
        self.pack_start(self.labelName, False, False, 3)
        self.pack_start(self.labelDescription, False, False, 3)
        self.pack_start(self.labelAuthor, False, False, 3)
        self.pack_start(self.labelWebsite, False, False, 3)
        self.pack_start(self.previewScroll, True, True, 3)
        self.updateInfosFrame()

        self.show_all()

    def updateInfosFrame(self):
        '''Updates the htmltextview preview.'''
        mgr = self.controller.conversationLayoutManager
        self.labelName.set_markup('<b>' + _('Name:') + '</b> ' + \
            mgr.getName())
        self.labelDescription.set_markup('<b>' + _('Description:') + '</b> ' +\
            mgr.getDescription())
        self.labelAuthor.set_markup('<b>' + _('Author:') + '</b> ' + \
            mgr.getAuthor())
        self.labelWebsite.set_markup('<b>' + _('Website:') + '</b> ' + \
            mgr.getWebsite())

        textbuff = self.preview.get_buffer()
        start, end = textbuff.get_bounds()
        textbuff.delete(start,end)

        html = mgr.getPreview()
        BODY = '<body>%s</body>'
        self.preview.display_html(BODY % html)

class InterfaceTab(gtk.VBox):
    '''This class represents the [...]'''

    def __init__(self, controller):
        '''Constructor'''

        gtk.VBox.__init__(self)

        self.controller = controller
        self.config = controller.config

        self.set_spacing(2)
        self.set_border_width(8)

        self.label = gtk.Label()

        def add(box, key, desc, size, packing=False, align=None, defsize=-1):
            widget = WidgetToggleBox(self.config, key, desc, self.label)
            widget.show()
            if type(box) == gtk.HBox:
                widget.set_size_request(size, defsize)
            else:
                widget.set_size_request(defsize, size)
            if align:
                align.add(widget)
                widget = align
            box.pack_start(widget, packing)

        self.windowshbox = gtk.HBox()

        self.maindescvbox = gtk.VBox()
        self.mainalign = gtk.Alignment(0.5, 0.5, 0.0, 0.0)
        self.mainvbox = gtk.VBox()
        self.mainvbox.set_size_request(60, -1)
        add(self.mainvbox, 'showMenu', _('Show _menu bar'), 10)
        add(self.mainvbox, 'showUserPanel', _('Show _user panel'), 20)
        if self.config.user['statusComboOnTop']:
            add(self.mainvbox, 'showStatusCombo', _('Show status _combo'), 10)
            add(self.mainvbox, 'showSearchEntry', _('Show _search entry'), 10)
            add(self.mainvbox, None, None, 80)
        else:
            add(self.mainvbox, 'showSearchEntry', _('Show _search entry'), 10)
            add(self.mainvbox, None, None, 80)
            add(self.mainvbox, 'showStatusCombo', _('Show status _combo'), 10)

        mainwindowlabel = gtk.Label()
        mainwindowlabel.set_markup('<b>' + _('Main window') + '</b>')
        mainwindowlabel.set_alignment(0.5, 0.0)
        self.mainalign.add(self.mainvbox)
        self.maindescvbox.pack_start(mainwindowlabel)
        self.maindescvbox.pack_start(self.mainalign, False)
        self.windowshbox.pack_start(self.maindescvbox)

        self.convdescvbox = gtk.VBox()
        self.convalign = gtk.Alignment(0.5, 0.5, 0.0, 0.0)
        self.convbox1 = gtk.VBox()
        self.convbox1.set_size_request(100, -1)
        add(self.convbox1, 'showMenubar', _('Show _menu bar'), 10)
        add(self.convbox1, 'showHeader', _('Show conversation _header'), 20)
        self.convbox2 = gtk.HBox()
        self.convbox3 = gtk.VBox()
        self.convbox4 = gtk.HBox()
        self.convbox5 = gtk.VBox()
        self.convbox1.pack_start(self.convbox2)
        self.convbox2.pack_start(self.convbox3)
        add(self.convbox3, None, None, 50)
        self.convbox3.pack_start(self.convbox4)
        self.convbox4.pack_start(self.convbox5)
        self.convbox4.set_size_request(-1, 30)
        add(self.convbox5, 'showToolbar', _('Show conversation _toolbar'), 10)
        add(self.convbox5, None, None, -1, packing=True)
        add(self.convbox4, 'showSendButton', _('S_how a Send button'), 15,
            align=gtk.Alignment(0.0, 0.5, 0.0, 0.0), defsize=10)

        add(self.convbox3, 'showStatusBar', _('Show st_atusbar'), 10)
        add(self.convbox2, 'showAvatars', _('Show a_vatars'), 30)

        convwindowlabel = gtk.Label()
        convwindowlabel.set_markup('<b>' + _('Conversation Window') + '</b>')
        convwindowlabel.set_alignment(0.5, 0.0)
        self.convalign.add(self.convbox1)
        self.convdescvbox.pack_start(convwindowlabel)
        self.convdescvbox.pack_start(self.convalign, True)
        self.windowshbox.pack_start(self.convdescvbox)

        self.pack_start(self.windowshbox)

        self.pack_start(self.label, True)

        self.checks = []
        mkcheck(self, 'windows', _('Use multiple _windows'))
        mkcheck(self, 'showTabCloseButton', _('Show close button on _each tab'))
        mkcheck(self, 'avatarsInUserList', _('Show _avatars in user list'))
        mkcheck(self, 'avatarsOnRight', _('Put avatars in the _right side'))
        mkcheck(self, 'statusComboOnTop', _('Put status combo on the top side (requires restart)'))
        mkcheck(self, 'avatarsInTaskbar', _('Show avatars in task_bar'))
        mkcheck(self, 'hideNewWindow', _('Hide new conversation window automatically'))
        mkcheck(self, 'showMailTyping', _('Show ma_il on "is typing" message'))
        mkcheck(self, 'disableEsc', _('Don\'t _close conversation by pressing ESC'))
        mkcheck(self, 'dontDisturbOnBusy', _('Don\'t disturb on busy _status'))
        mkcheck(self, 'preventClosingTime', _('Prevent closing window when a new message arrives'))

        self.show_all()


    def onToggled(self, radio, option):
        self.config.user[option] = radio.get_active()

    def save(self):
        pass

class ProxySettings(gtk.VBox):
    '''This class represents the panel with the proxy variables
    in the config file'''

    def __init__(self, config):
        '''Constructor'''

        gtk.VBox.__init__(self)

        self.config = config

        self.set_spacing(8)
        self.set_border_width(8)

        self.useProxy = gtk.CheckButton(_('_Use proxy'))
        self.useProxy.set_active(self.config.glob['useProxy'])

        self.host = gtk.Entry()
        self.host.set_text(self.config.glob['proxyHost'])
        self.port = gtk.Entry()
        self.port.set_text(str(self.config.glob['proxyPort']))
        self.username = gtk.Entry()
        self.username.set_text(str(self.config.glob['proxyUsername']))
        self.password = gtk.Entry()
        self.password.set_text(str(self.config.glob['proxyPassword']))
        self.password.set_visibility(False)
        
        table = gtk.Table(2, 4)
        table.set_row_spacings(2)
        table.set_col_spacings(2)

        host = gtk.Label(_('_Host:'))
        host.set_alignment(0.0, 0.5)
        host.set_use_underline(True)
        host.set_mnemonic_widget(self.host)
        port = gtk.Label(_('_Port:'))
        port.set_alignment(0.0, 0.5)
        port.set_use_underline(True)
        port.set_mnemonic_widget(self.port)
        username = gtk.Label(_('_Username:'))
        username.set_alignment(0.0, 0.5)
        username.set_use_underline(True)
        username.set_mnemonic_widget(self.username)
        password = gtk.Label(_('Pass_word:'))
        password.set_alignment(0.0, 0.5)
        password.set_use_underline(True)
        password.set_mnemonic_widget(self.password)
        table.attach(host, 0, 1, 0, 1)
        table.attach(port , 0, 1, 1, 2)
        table.attach(username, 0, 1, 2, 3)
        table.attach(password , 0, 1, 3, 4)

        table.attach(self.host, 1, 2, 0, 1)
        table.attach(self.port, 1, 2, 1, 2)
        table.attach(self.username, 1, 2, 2, 3)
        table.attach(self.password, 1, 2, 3, 4)

        self.useProxyToggled(self.useProxy)
        self.useProxy.connect('toggled', self.useProxyToggled)
        self.pack_start(self.useProxy)
        self.pack_start(table)


        self.show_all()

    def save(self):
        '''save the actual setting'''

        host = self.host.get_text()
        if host.startswith('http://'):
            host = host.split('http://')[1]
        if host.find('/') != -1:
            host = host.split('/')[0]

        self.config.glob['useProxy'] = self.useProxy.get_active()
        self.config.glob['proxyHost'] = host
        self.config.glob['proxyPort'] = self.port.get_text()
        self.config.glob['proxyUsername'] = self.username.get_text()
        self.config.glob['proxyPassword'] = self.password.get_text()

    def useProxyToggled(self, check):
        '''callback for the toggled signal'''

        if self.useProxy.get_active():
            self.host.set_sensitive(True)
            self.port.set_sensitive(True)
            self.username.set_sensitive(True)
            self.password.set_sensitive(True)
        else:
            self.host.set_sensitive(False)
            self.port.set_sensitive(False)
            self.username.set_sensitive(False)
            self.password.set_sensitive(False)

class FTSettings(gtk.VBox):
    '''This class represents the panel with the filetransfer settings'''

    def __init__(self, controller):
        '''Constructor'''

        gtk.VBox.__init__(self)

        self.config = controller.config
        self.pathChooser = gtk.FileChooserDialog(
            title=_('Choose a Directory'),
            action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
            buttons=(
                gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                gtk.STOCK_OPEN, gtk.RESPONSE_OK)
            )

        self.set_spacing(8)
        self.set_border_width(8)

        self.checks = []
        mkcheck(self, 'receivedFilesSortedByUser',
            _('Sort received _files by sender'))

        targetbutton = gtk.FileChooserButton(self.pathChooser)
        targetbutton.set_current_folder(os.path.expanduser(
            self.config.user['receivedFilesDir']))

        target = gtk.Label(_('_Save files to:'))
        target.set_alignment(0.0, 0.5)
        target.set_use_underline(True)
        self.pack_start(target, False)
        self.pack_start(targetbutton, False)

    def onToggled(self, radio, option):
        self.config.user[option] = radio.get_active()

    def save(self):
        self.config.user['receivedFilesDir'] = self.pathChooser.get_filename()
        
class PrivacyTab(gtk.VBox):
    '''This class represents the panel with the privacy settings'''

    def __init__(self, controller):
        '''Constructor'''

        gtk.VBox.__init__(self)

        self.controller = controller

        hbox = gtk.HBox()
        self.add(hbox) 

        scroll1 = gtk.ScrolledWindow()
        scroll1.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
        hbox.add(scroll1)
        self.model1 = gtk.ListStore(gobject.TYPE_STRING)
        self.view1 = gtk.TreeView(self.model1)
        self.view1.connect('button-press-event', self.right_click1)
        self.view1.connect("key-press-event", self.onKeyPressOfView1)
        scroll1.add(self.view1)
        render1 = gtk.CellRendererText()
        col1 = gtk.TreeViewColumn(_('Allow list:'), render1, text=0)
        col1.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
        col1.set_cell_data_func(render1, self.func)
        self.view1.append_column(col1)

        vbox = gtk.VBox()
        button1 = gtk.Button()
        image1 = gtk.image_new_from_stock(gtk.STOCK_GO_BACK, gtk.ICON_SIZE_BUTTON)
        button1.set_image(image1)
        button1.connect('clicked', self.unblock)
        button2 = gtk.Button()
        image2 = gtk.image_new_from_stock(gtk.STOCK_GO_FORWARD, gtk.ICON_SIZE_BUTTON)
        button2.set_image(image2)
        button2.connect('clicked', self.block)
        vbox.pack_start(button1, True, False)
        vbox.pack_start(button2, True, False)
        hbox.pack_start(vbox, False)
 
        scroll2 = gtk.ScrolledWindow()
        scroll2.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
        hbox.add(scroll2)
        self.model2 = gtk.ListStore(gobject.TYPE_STRING)
        self.view2 = gtk.TreeView(self.model2)
        self.view2.connect('button-press-event', self.right_click2)
        self.view2.connect("key-press-event", self.onKeyPressOfView2)
        scroll2.add(self.view2)
        render2 = gtk.CellRendererText()
        col2 = gtk.TreeViewColumn(_('Block list:'), render2, text=0)
        col2.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
        col2.set_cell_data_func(render2, self.func)
        self.view2.append_column(col2)

        for contact in self.controller.msn.contactManager.lists['Allow']:
            self.model1.append([contact])
        for contact in self.controller.msn.contactManager.lists['Block']:
            self.model2.append([contact])

        ##Draw the statusBar
        eventBox = gtk.EventBox()
        box = gtk.HBox(False, 0)
        otherBox = gtk.VBox(False, 0)
        box.set_size_request(40, 40)
        eventBox.add(box)
        eventBox.modify_bg(gtk.STATE_NORMAL, self.controller.tooltipColor)
        firstLabel = gtk.Label(_('Yellow contacts are not in your contact list'))
        secondLabel = gtk.Label(_('Purple contacts don\'t have you in their contact list'))
        image = gtk.image_new_from_stock(gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_LARGE_TOOLBAR)
        box.pack_start(image, False, False, 10)
        otherBox.pack_start(firstLabel, False, False, 2)
        otherBox.pack_start(secondLabel, False, False, 2)
        box.pack_start(otherBox, False, False, 10) 
        self.pack_start(eventBox, False, False, 5)       
 
    def right_click1(self, view, event):
        '''Occurs when somebody clicks in the allow list'''
        selection = self.view2.get_selection()
        selection.unselect_all()
        path = view.get_path_at_pos(int(event.x),int(event.y))
        if not path:
            selection = view.get_selection()
            selection.unselect_all()
            return
        if event.button != 3:
            return
        iter = self.model1.get_iter(path[0])
        contact = self.model1.get_value(iter, 0)

        menu = gtk.Menu()
        item1 = gtk.MenuItem(_('Add to conacts'))
        item1.connect('activate', self.addcon, contact)
        menu.append(item1)
        if contact in self.controller.msn.contactManager.contacts:
            item1.set_state(gtk.STATE_INSENSITIVE)
        item2 = gtk.MenuItem(_('Move to block list'))
        item2.connect('activate', self.block, iter)
        menu.append(item2)
        item3 = gtk.MenuItem(_('Delete'))
        item3.connect('activate', self.deleteConfirmation1, iter)
        if contact in self.controller.msn.contactManager.lists['Reverse']:
            item3.set_state(gtk.STATE_INSENSITIVE)
        menu.append(item3)
        menu.popup(None, None, None, event.button, event.time)
        menu.show_all()

    def right_click2(self, view, event):
        '''Occurs when somebody clicks in the block list'''
        selection = self.view1.get_selection()
        selection.unselect_all()
        path = view.get_path_at_pos(int(event.x),int(event.y))
        if not path:
            selection = view.get_selection()
            selection.unselect_all()
            return
        if event.button != 3:
            return
        iter = self.model2.get_iter(path[0])
        contact = self.model2.get_value(iter, 0)

        menu = gtk.Menu()
        item1 = gtk.MenuItem(_('Add to conacts'))
        item1.connect('activate', self.addcon, contact)
        menu.append(item1)
        if contact in self.controller.msn.contactManager.contacts:
            item1.set_state(gtk.STATE_INSENSITIVE)
        item2 = gtk.MenuItem(_('Move to allow list'))
        item2.connect('activate', self.unblock, iter)
        menu.append(item2)
        item3 = gtk.MenuItem(_('Delete'))
        item3.connect('activate', self.deleteConfirmation2, iter)
        if contact in self.controller.msn.contactManager.lists['Reverse']:
            item3.set_state(gtk.STATE_INSENSITIVE)
        menu.append(item3)
        menu.popup(None, None, None, event.button, event.time)
        menu.show_all()

    def addcon(self, item, contact):
        self.controller.contacts.add(contact)

    def delete1(self, item, iter):
        contact = self.model1.get_value(iter, 0)
        self.model1.remove(iter)
        self.controller.msn.contactManager.lists['Allow'].remove(contact)
        if self.controller.contacts.exists(contact):
            self.controller.msn.removeUser(contact)
        if contact not in self.controller.msn.contactManager.contacts:
            soap.requests.delete_role(self.controller.msn.proxy, 'Allow', contact, None, None)

    def delete2(self, item, iter):
        contact = self.model2.get_value(iter, 0)
        self.model2.remove(iter)
        self.controller.msn.contactManager.lists['Block'].remove(contact)
        if self.controller.contacts.exists(contact):
            self.controller.msn.removeUser(contact)
        if contact not in self.controller.msn.contactManager.contacts:
            soap.requests.delete_role(self.controller.msn.proxy, 'Block', contact, None, None)

    def block(self, button, iter=None):
        if not iter:
            iter = self.view1.get_selection().get_selected()[1]
            if not iter:
                return
        contact = self.model1.get_value(iter, 0)
        self.model1.remove(iter)
        self.model2.append([contact])
        if contact in self.controller.msn.contactManager.contacts:
            self.controller.contacts.block(contact)
        else:
            self.controller.msn.blockUser(contact)

    def unblock(self, button, iter=None):
        if not iter:
            iter = self.view2.get_selection().get_selected()[1]
            if not iter:
                return
        contact = self.model2.get_value(iter, 0)
        self.model2.remove(iter)
        self.model1.append([contact])
        if contact in self.controller.msn.contactManager.contacts:
            self.controller.contacts.unblock(contact)
        else:
            self.controller.msn.unblockUser(contact)

    def func(self, column, render, model, iter):
        contact = model.get_value(iter, 0)
        if contact not in self.controller.msn.contactManager.lists['Reverse']:
            render.set_property('background', '#FF00FF')
        elif contact not in self.controller.msn.contactManager.contacts:
            render.set_property('background', '#FFF000')
        else:
            render.set_property('background', None)

    def onKeyPressOfView1(self , widget, event):
        '''called when the user press a key'''
        if event.keyval == gtk.keysyms.Right or event.keyval == gtk.keysyms.Return:
            self.block(None)

    def onKeyPressOfView2(self , widget, event):
        '''called when the user press a key'''
        if event.keyval == gtk.keysyms.Left or event.keyval == gtk.keysyms.Return:
            self.unblock(None)

    def manageDeleteConfirmation1(self, *args):
        iter = args[1]
        if args[0] == abstract.stock.YES:
            self.delete1(None, iter)

    def deleteConfirmation1(self, item, iter):
        contactName = self.model1.get_value(iter, 0)
        message = _('Are you sure you want to delete %s from your authorized contacts?') % contactName
        dialog.yes_no(message, self.manageDeleteConfirmation1, iter)

    def manageDeleteConfirmation2(self, *args):
        iter = args[1]
        if args[0] == abstract.stock.YES:
            self.delete2(None, iter)

    def deleteConfirmation2(self, item, iter):
        contactName = self.model2.get_value(iter, 0)
        message = _('Are you sure you want to delete %s from your blocked contacts?') % contactName
        dialog.yes_no(message, self.manageDeleteConfirmation2, iter)

class WebcamTab(gtk.VBox):
    '''This class represents the panel with the Webcam settings'''

    def __init__(self, controller):
        '''Constructor'''

        gtk.VBox.__init__(self)

        self.config = controller.config
        self.controller = controller
        self.webcam = None
        self.webcamList = []
        self.movie_window = gtk.DrawingArea()
        self.movie_window.set_colormap(gtk.gdk.colormap_get_system())
        self.movie_window.set_size_request(320,240)

        devLabel = gtk.Label(_('Select webcam you want to use for your conferences:'))
        devLabel.set_alignment(0.0, 0.5)
        devLabel.set_use_underline(True)
        
        devHBox = gtk.HBox()

        self.combobox = gtk.combo_box_new_text()
        self.get_device_list()
        self.combobox.connect('changed', self.on_set_device)

        devHBox.pack_start(self.combobox)
	
        self.hadj = gtk.Adjustment(controller.config.user['webcamHue'], -1.0, 1.0, 0.1)
        self.sadj = gtk.Adjustment(controller.config.user['webcamSaturation'], 0.0, 2.0, 0.1)
        self.badj = gtk.Adjustment(controller.config.user['webcamBrightness'], -1.0, 1.0, 0.1)
        self.cadj = gtk.Adjustment(controller.config.user['webcamContrast'], 0.0, 2.0, 0.1)

        self.hue = gtk.HScale(self.hadj)
        self.saturation = gtk.HScale(self.sadj)
        self.brightness = gtk.HScale(self.badj)
        self.contrast = gtk.HScale(self.cadj)

        hueLabel= gtk.Label(_('Hue:'))
        satLabel= gtk.Label(_('Saturation:'))
        conLabel= gtk.Label(_('Contrast:'))
        briLabel= gtk.Label(_('Brightness:'))

        hueHBox= gtk.HBox()
        satHBox= gtk.HBox()
        conHBox= gtk.HBox()
        briHBox= gtk.HBox()

        hueHBox.set_homogeneous(True)
        satHBox.set_homogeneous(True)
        conHBox.set_homogeneous(True)
        briHBox.set_homogeneous(True)

        hueHBox.pack_start(hueLabel)
        hueHBox.pack_start(self.hue)
        satHBox.pack_start(satLabel)
        satHBox.pack_start(self.saturation)
        conHBox.pack_start(conLabel)
        conHBox.pack_start(self.contrast)
        briHBox.pack_start(briLabel)
        briHBox.pack_start(self.brightness)

        self.defButton = gtk.Button(_('Restore Defaults'))
        self.defButton.connect('clicked', self.on_set_default)
        self.defButton.set_sensitive(False)

        self.hue.set_sensitive(False);
        self.saturation.set_sensitive(False);
        self.contrast.set_sensitive(False);
        self.brightness.set_sensitive(False);

        self.hadj.connect('value-changed',self.on_hue_changed)
        self.sadj.connect('value-changed',self.on_saturation_changed)
        self.badj.connect('value-changed',self.on_brightness_changed)
        self.cadj.connect('value-changed',self.on_contrast_changed)

        self.set_spacing(1)
        self.set_border_width(3)
        self.pack_start(self.movie_window,False,False)
        self.pack_start(devLabel)
        self.pack_start(devHBox, False)
        self.pack_start(hueHBox, False)
        self.pack_start(satHBox, False)
        self.pack_start(briHBox, False)
        self.pack_start(conHBox, False)
        self.pack_start(self.defButton)

    def get_device_list(self):
        if not HAVE_WEBCAM:
            return
    
        for device, name in WebcamDevice.list_devices():
            self.combobox.append_text(name)
            self.webcamList.append((device, name))
         
    def on_set_device(self,button):
        if not HAVE_WEBCAM or self.combobox.get_active() < 0:
            return
        self.config.user['webcamDevice'] = self.webcamList[self.combobox.get_active()][0]
        if self.webcam is not None:
            self.webcam.stop()
        self.webcam = WebcamDevice.WebcamDevice(None, self.movie_window.window.xid ,self.controller)
        self.defButton.set_sensitive(True)
        self.hue.set_sensitive(True)
        self.saturation.set_sensitive(True)
        self.brightness.set_sensitive(True)
        self.contrast.set_sensitive(True)

    def on_set_default(self,button):
        self.hue.set_value(0.0)
        self.saturation.set_value(1.0)
        self.contrast.set_value(1.0)
        self.brightness.set_value(0.0)

    def on_hue_changed(self,adj):
        if not HAVE_WEBCAM:
            return
        self.webcam.setHue(adj.value)

    def on_saturation_changed(self,adj):
        if not HAVE_WEBCAM:
            return
        self.webcam.setSaturation(adj.value)

    def on_brightness_changed(self,adj):
        if not HAVE_WEBCAM:
            return
        self.webcam.setBrightness(adj.value)

    def on_contrast_changed(self,adj):
        if not HAVE_WEBCAM:
            return
        self.webcam.setContrast(adj.value)

    def save(self):
        if self.webcam is not None:
            self.webcam.stop()
        if self.combobox.get_active() > 0:
            self.config.user['webcamDevice'] = self.webcamList[self.combobox.get_active()][0]
        self.config.user['webcamContrast'] = self.cadj.value
        self.config.user['webcamHue'] = self.hadj.value
        self.config.user['webcamBrightness'] = self.badj.value
        self.config.user['webcamSaturation'] = self.sadj.value
       

def mkcheck(self, id, label):
    '''little helper function to add checkbuttons'''
    check = gtk.CheckButton(label)
    check.set_active(self.config.user[id])
    check.connect('toggled', self.onToggled, id)
    self.pack_start(check, False, False, padding=0)
    setattr(self, id, check)
    self.checks.append(id)

# moved from emesenecommon
def rgbToHexa(color):
    '''take a gtk.gdk.Color end returns a string with html way color.
    Eg.: #FFCC00'''

    red = color.red >> 8
    green = color.green >> 8
    blue = color.blue >> 8

    return '#'+'%02X%02X%02X' % (red, green, blue)
